Lru 缓存替换策略及 Csharp 实现

元数据

作者: Cnblogs.com
标题: Lru 缓存替换策略及 C# 实现
分类: #dotnet
地址: https://www.cnblogs.com/eventhorizon/p/17290125.html

笔记

进一步优化 跳转

public class LRUCache_V3<TKey, TValue>
{
	private readonly DoubleLinkedListNode<TKey, TValue> _head;
	private readonly DoubleLinkedListNode<TKey, TValue> _tail;
	private readonly Dictionary<TKey, DoubleLinkedListNode<TKey, TValue>> _dictionary;
	private readonly int _capacity;
	public LRUCache_V3(int capacity)
	{
		_capacity = capacity;
		_head = new DoubleLinkedListNode<TKey, TValue>();
		_tail = new DoubleLinkedListNode<TKey, TValue>();
		_head.Next = _tail;
		_tail.Previous = _head;
		_dictionary = new Dictionary<TKey, DoubleLinkedListNode<TKey, TValue>>();
	}
	public TValue Get(TKey key)
	{
		if (_dictionary.TryGetValue(key, out var node))
		{
			RemoveNode(node);
			AddLastNode(node);
			return node.Value;
		}
		return default;
	}
	public void Put(TKey key, TValue value)
	{
		if (_dictionary.TryGetValue(key, out var node))
		{
			RemoveNode(node);
			AddLastNode(node);
			node.Value = value;
		}
		else
		{
			if (_dictionary.Count == _capacity)
			{
				var firstNode = RemoveFirstNode();
				_dictionary.Remove(firstNode.Key);
			}
			var newNode = new DoubleLinkedListNode<TKey, TValue>(key, value);
			AddLastNode(newNode);
			_dictionary.Add(key, newNode);
		}
	}
	public void Remove(TKey key)
	{
		if (_dictionary.TryGetValue(key, out var node))
		{
			_dictionary.Remove(key);
			RemoveNode(node);
		}
	}
	private void AddLastNode(DoubleLinkedListNode<TKey, TValue> node)
	{
		node.Previous = _tail.Previous;
		node.Next = _tail;
		_tail.Previous.Next = node;
		_tail.Previous = node;
	}
	private DoubleLinkedListNode<TKey, TValue> RemoveFirstNode()
	{
		var firstNode = _head.Next;
		_head.Next = firstNode.Next;
		firstNode.Next.Previous = _head;
		firstNode.Next = null;
		firstNode.Previous = null;
		return firstNode;
	}
	private void RemoveNode(DoubleLinkedListNode<TKey, TValue> node)
	{
		node.Previous.Next = node.Next;
		node.Next.Previous = node.Previous;
		node.Next = null;
		node.Previous = null;
	}
	internal class DoubleLinkedListNode<TKey, TValue>
	{ 
		public DoubleLinkedListNode()
		{
		}
		public DoubleLinkedListNode(TKey key, TValue value)
		{
			Key = key;
			Value = value;
		}
		public TKey Key { get; set; }
		public TValue Value { get; set; }
		public DoubleLinkedListNode<TKey, TValue> Previous { get; set; }
		public DoubleLinkedListNode<TKey, TValue> Next { get; set; }
	}
}